#!/usr/bin/env python
# -*- coding=utf-8 -*-

'''
This part is for matching hall symbol
'''

import numpy as np
import halldata


change_of_b_mono = [
    np.array([[1, 0, 0],  # /* b  first turn; two axes are flipped in second turn */
               [0, 1, 0],
               [0, 0, 1]]),
    np.array([[0, 0, 1],  # /* b */
               [0, -1, 0],
               [1, 0, 0]]),
    np.array([[0, 0, 1],  # /* a */
               [1, 0, 0],
               [0, 1, 0]]),
    np.array([[1, 0, 0],  # /* c */
               [0, 0, 1],
               [0, -1, 0]]),
    np.array([[0, 1, 0],  # /* c */
               [0, 0, 1],
               [1, 0, 0]]),
    np.array([[0, -1, 0],  # /* a */
               [1, 0, 0],
               [0, 0, 1]]),
    np.array([[-1, 0, 1],  # /* b */
               [0, 1, 0],
               [-1, 0, 0]]),
    np.array([[1, 0, -1],  # /* b */
               [0, -1, 0],
               [0, 0, -1]]),
    np.array([[0, 1, -1],  # /* a */
               [1, 0, 0],
               [0, 0, -1]]),
    np.array([[-1, -1, 0],  # /* c */
               [0, 0, 1],
               [-1, 0, 0]]),
    np.array([[1, -1, 0],  # /* c */
               [0, 0, 1],
               [0, -1, 0]]),
    np.array([[0, 1, 1],  # /* a */
               [1, 0, 0],
               [0, 1, 0]]),
    np.array([[0, 0, -1],  # /* b */
               [0, 1, 0],
               [1, 0, -1]]),
    np.array([[-1, 0, 0],  # /* b */
               [0, -1, 0],
               [-1, 0, 1]]),
    np.array([[0, -1, 0],  # /* a */
               [1, 0, 0],
               [0, -1, 1]]),
    np.array([[0, 1, 0],  # /* c */
               [0, 0, 1],
               [1, 1, 0]]),
    np.array([[-1, 0, 0],  # /* c */
               [0, 0, 1],
               [-1, 1, 0]]),
    np.array([[0, 0, -1],  # /* a */
               [1, 0, 0],
               [0, -1, -1]]),
    np.array([[1, 0, 0],  # /* b  two axes are flipped to look for non-acute axes */
               [0, -1, 0],
               [0, 0, -1]]),
    np.array([[0, 0, -1],  # /* b */
               [0, 1, 0],
               [1, 0, 0]]),
    np.array([[0, 0, 1],  # /* a */
               [-1, 0, 0],
               [0, -1, 0]]),
    np.array([[-1, 0, 0],  # /* c */
               [0, 0, -1],
               [0, -1, 0]]),
    np.array([[0, 1, 0],  # /* c */
               [0, 0, -1],
               [-1, 0, 0]]),
    np.array([[0, 1, 0],  # /* a */
               [-1, 0, 0],
               [0, 0, 1]]),
    np.array([[-1, 0, -1],  # /* b */
               [0, -1, 0],
               [-1, 0, 0]]),
    np.array([[1, 0, 1],  # /* b */
               [0, 1, 0],
               [0, 0, 1]]),
    np.array([[0, -1, -1],  # /* a */
               [-1, 0, 0],
               [0, 0, -1]]),
    np.array([[1, -1, 0],  # /* c */
               [0, 0, -1],
               [1, 0, 0]]),
    np.array([[-1, -1, 0],  # /* c */
               [0, 0, -1],
               [0, -1, 0]]),
    np.array([[0, -1, 1],  # /* a */
               [-1, 0, 0],
               [0, -1, 0]]),
    np.array([[0, 0, 1],  # /* b */
               [0, -1, 0],
               [1, 0, 1]]),
    np.array([[-1, 0, 0],  # /* b */
               [0, 1, 0],
               [-1, 0, -1]]),
    np.array([[0, 1, 0],  # /* a */
               [-1, 0, 0],
               [0, 1, 1]]),
    np.array([[0, 1, 0],  # /* c */
               [0, 0, -1],
               [-1, 1, 0]]),
    np.array([[1, 0, 0],  # /* c */
               [0, 0, -1],
               [1, 1, 0]]),
    np.array([[0, 0, -1],  # /* a */
               [-1, 0, 0],
               [0, 1, -1]])]

change_of_cen_mono = [
    'C_FACE',  # /* first turn */
    'A_FACE',
    'B_FACE',
    'B_FACE',
    'A_FACE',
    'C_FACE',
    'A_FACE',
    'C_FACE',
    'C_FACE',
    'A_FACE',
    'B_FACE',
    'B_FACE',
    'BASE',
    'BASE',
    'BASE',
    'BASE',
    'BASE',
    'BASE',
    'C_FACE',  # /* second turn */
    'A_FACE',
    'B_FACE',
    'B_FACE',
    'A_FACE',
    'C_FACE',
    'A_FACE',
    'C_FACE',
    'C_FACE',
    'A_FACE',
    'B_FACE',
    'B_FACE',
    'BASE',
    'BASE',
    'BASE',
    'BASE',
    'BASE',
    'BASE'
]

change_of_uni_ax_mono = [
    1, 1, 0, 2, 2, 0, 1, 1, 0, 2, 2, 0, 1, 1, 0, 2, 2, 0,
    1, 1, 0, 2, 2, 0, 1, 1, 0, 2, 2, 0, 1, 1, 0, 2, 2, 0]

change_of_b_ortho = [np.array([[1, 0, 0],
                               [0, 1, 0],
                               [0, 0, 1]]),
                     np.array([[0, 0, 1],
                               [1, 0, 0],
                               [0, 1, 0]]),
                     np.array([[0, 1, 0],
                               [0, 0, 1],
                               [1, 0, 0]]),
                     np.array([[0, 1, 0],
                               [1, 0, 0],
                               [0, 0, -1]]),
                     np.array([[1, 0, 0],
                               [0, 0, 1],
                               [0, -1, 0]]),
                     np.array([[0, 0, 1],
                               [0, 1, 0],
                               [-1, 0, 0]])]

change_of_cen_ortho = ['C_FACE', 'B_FACE', 'A_FACE', 'C_FACE', 'B_FACE', 'A_FACE']

change_of_uni_ax_ortho = [2, 1, 0, 2, 1, 0]

hR_to_hP = np.array([[1, 0, 1],
                     [-1, 1, 1],
                     [0, -1, 1]])

change_of_b_501 = np.array([[0, 0, 1],
                            [0, -1, 0],
                            [1, 0, 0]])

A_mat = np.array([[1, 0, 0],
                  [0, 1./2, -1./2],
                  [0, 1./2, 1./2]])

B_mat = np.array([[1./2, 0, -1./2],
                  [0, 1, 0],
                  [1./2, 0, 1./2]])

C_mat = np.array([[1./2, 1./2, 0],
                  [-1./2, 1./2, 0],
                  [0, 0, 1]])

R_mat = np.array([[2./3,-1./3,-1./3],
                  [1./3, 1./3,-2./3],
                  [1./3, 1./3, 1./3]])

I_mat = np.array([[-1./2, 1./2, 1./2],
                  [1./2,-1./2, 1./2],
                  [1./2, 1./2, -1./2]])

F_mat = np.array([[0, 1./2, 1./2],
                  [1./2, 0, 1./2],
                  [1./2, 1./2, 0]])

tricli_VSpU = [
        [ #/* 1 */
            [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
            [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
            [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
         ],
        [ #/* 2 */
            [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
            [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
            [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
        ],
    ]

tricli_generators = [
  [ #/* 1 */
    [  1, 0, 0, 0, 1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  1, 0, 0, 0, 1, 0, 0, 0, 1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
]

mono_VSpU = [
  [ #/* 1 */
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
]

mono_A_VSpU = [
  [ #/* 1 */
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, -1, 0, 0, 1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 1, 0, 0, -1.0/2, 0,  0,  0,  0, ],
  ],
]

mono_B_VSpU = [
  [ #/* 1 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
  ],
]

mono_C_VSpU = [
  [ #/* 1 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
]

mono_I_VSpU = [
  [ #/* 1 */
    [ -1.0/2, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 1.0/2, -1, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1, 1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ -1, 0, 1.0/2,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ 0, 1, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, 1.0/2, 0, -1.0/2,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 1, -1.0/2, 0, -1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, -1.0/2, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
]

mono_generators = [
  [ #/* 1 */
    [  1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  -1, 0, 0, 0, 1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [  -1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [  -1, 0, 0, 0, 1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [  1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [  1, 0, 0, 0, 1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [  1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [  -1, 0, 0, 0, 1, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [  -1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
]

ortho_VSpU = [
  [ #/* 1 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ -1.0/2, 0, 0, 0, 0, 0, 0, 0, 0, ],
    [ 0, 0, 0, 0, -1.0/2, 0, 0, 0, 0, ],
    [ 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, ],
  ],
]

ortho_F_VSpU = [
  [ #/* 1 */
    [ 0, 1.0/2, 0, -1.0/4, -1.0/4, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, -1.0/4, -1.0/4, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, -1.0/4, 3.0/4, 0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ 0, 1, 0, 0, -1, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, -1, 0, 0, 1, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ 0, -1, 0, 0, 1, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 1, 0, 0, 0, 0, 0, -1.0/2, 0, ],
    [ 0, 0, 0, 0, 0, 0, 0, -1.0/2, 0, ],
    [ 0, 0, 0, 0, 1, 0, 0, -1.0/2, 0, ],
  ],
]

ortho_I_VSpU = [
  [ #/* 1 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1.0/2, -1.0/2, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0, 0, 1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1.0/2, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, 1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1.0/2, 0, 0, 0, 1.0/2, 0,  0,  0,  0, ],
    [ -1.0/2, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, -1.0/2, 0, -1, 0, 1.0/2, 0, 0, ],
    [ 0, 0, -1.0/2, 0, 0, 0, 0, 0, 0, ],
  ],
]

ortho_A_VSpU = [
  [ #/* 1 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 1, 0, 0, -1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, -1, 0, 0, 1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ -1.0/2, 0, 0, 0, 0, 0, 0, 0, 0, ],
    [ 0, -1, 0, 0, 0, -1.0/2, 0, 0, 0, ],
    [ 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, ],
  ],
]

ortho_B_VSpU = [
  [ #/* 1 */
    [ -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ 0, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1.0/2, 0, 0, 1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, 0, 0, -1.0/2, 0, 0, 0, 0, ],
    [ 0, 0, 0, -1, 0, 0, 1.0/2, 0, 0, ],
  ],
]

ortho_C_VSpU = [
  [ #/* 1 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1.0/2, 0, 0, 1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 1.0/2, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ 0, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, ],
  ],
]

ortho_generators = [
  [ #/* 1 */
    [  -1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [  1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  -1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [  -1, 0, 0, 0, 1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [  1, 0, 0, 0, 1, 0, 0, 0, -1, ],
    [  1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [  1, 0, 0, 0, 1, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, 1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [  -1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [  1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
]

tetra_VSpU = [
  [ #/* 1 */
    [ -1.0/2, 1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ -1.0/2, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1, 0, 0, 0, 1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1.0/2, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 1.0/2, -1.0/2, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ -1, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ -1, 0, 0, 0, 1.0/2, 0, 0, 0, 0, ],
    [ 0, 0, 0, 0, -1.0/2, 0, 0, 0, 0, ],
    [ 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, ],
  ],
]

tetra_I_VSpU = [
  [ #/* 1 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, -1, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, -1, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ -1, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 0, -1, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -3.0/4, 1.0/4, 1.0/4,  0,  0,  0,  0,  0,  0, ],
    [ -1.0/4, -1.0/4, -1.0/4,  0,  0,  0,  0,  0,  0, ],
    [ -1.0/2, 1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, -1, -1, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ -3.0/4, 1.0/4, 0, 0, 1.0/4, 0,  0,  0,  0, ],
    [ -1.0/4, -1.0/4, 0, 0, -1.0/4, 0,  0,  0,  0, ],
    [ -1.0/2, 1.0/2, 0, 0, -1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 2, 0, -1.0/2, 0, -1,  0,  0,  0, ],
    [ 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ -1, 0, 0, 0, -1, 0, 1.0/2, 0, -1.0/2, ],
    [ 0, 0, 0, 0, -1, 0, 1.0/2, 0, -1.0/2, ],
    [ 1, 0, 0, 0, 1, 0, -1, 0, 0, ],
  ],
]

tetra_generators = [
  [ #/* 1 */
    [  0, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  0, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [  0, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  -1, 0, 0, 0, 1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [  0, 1, 0, -1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [  0, 1, 0, -1, 0, 0, 0, 0, -1, ],
    [  1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [  0, 1, 0, -1, 0, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, 1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [  0, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [  0, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
]

trigo_VSpU = [
  [ #/* 1 */
    [ -2.0/3, 1.0/3, 0,  0,  0,  0,  0,  0,  0, ],
    [ -1.0/3, -1.0/3, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ 0, 1.0/3, 0, -2.0/3, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/3, 0, -1.0/3, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, -1, 0, -2, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ 0, -1, 0, -2, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, 1.0/3, 0, -2.0/3, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/3, 0, -1.0/3, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ 0, -1, 0,  0,  0,  0,  0,  0,  0, ],
    [ 1, -1, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, -1, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 0, -1, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, 1, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ 0, -1, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, 1, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 10 */
    [ 0, -1, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 11 */
    [ -6, 3, 0, 4, 0, 0,  0,  0,  0, ],
    [ -3, 1, 0, 2, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 12 */
    [ 0, 1, 0, -2, 0, 0, 1, 0, 0, ],
    [ 0, -1, 0, 1, 0, 0, -1, 0, 0, ],
    [ 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, ],
  ],
  [ #/* 13 */
    [ 0, -1, 0, -2, 0, 0, 0, 0, 0, ],
    [ 0, -1, 0, -1, 0, 0, 0, 0, 0, ],
    [ 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, ],
  ],
]

trigo_generators = [
  [ #/* 1 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [  0, 1, 0, -1, 1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [  0, 1, 0, -1, 1, 0, 0, 0, -1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [  0, 1, 0, -1, 1, 0, 0, 0, -1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [  0, 1, 0, -1, 1, 0, 0, 0, -1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 10 */
    [  0, 1, 0, -1, 1, 0, 0, 0, -1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 11 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 12 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
  [ #/* 13 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
]

rhombo_h_VSpU = [
  [ #/* 1 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 1,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ -1.0/2, -1, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1.0/2, -1.0/2, 1.0/2,  0,  0,  0,  0,  0,  0, ],
    [ 1.0/2, -1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, ],
    [ -1.0/2, 1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, -1, 0, 0, 1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 1, 0, -1, -1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1.0/2, -1, 0, 1.0/2, 0, 0,  0,  0,  0, ],
    [ -1.0/2, 0, 0, 1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, 1, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, -1, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, 0, -1, 0, 0, 1.0/2, 0, 0, ],
  ],
]

rhombo_h_generators = [
  [ #/* 1 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [  0, 1, 0, -1, 1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [  0, 1, 0, -1, 1, 0, 0, 0, -1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [  0, 1, 0, -1, 1, 0, 0, 0, -1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [  0, -1, 0, 1, -1, 0, 0, 0, 1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
]

rhombo_p_VSpU = [
  [ #/* 1 */
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 1,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ -1.0/2, -1, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1.0/2, -1.0/2, 1.0/2,  0,  0,  0,  0,  0,  0, ],
    [ 1.0/2, -1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, ],
    [ -1.0/2, 1.0/2, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 0, -1, 0, 0, 1.0/2, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, 1, 0, -1, -1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ -1.0/2, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1.0/2, -1, 0, 1.0/2, 0, 0,  0,  0,  0, ],
    [ -1.0/2, 0, 0, 1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, 1, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 1, 0, 0, -1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, -1, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, 0, -1, 0, 0, 1.0/2, 0, 0, ],
  ],
]

rhombo_p_generators = [
  [ #/* 1 */
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [  0, 0, -1, 0, -1, 0, -1, 0, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [  0, 0, 1, 0, 1, 0, 1, 0, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [  0, 0, -1, -1, 0, 0, 0, -1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [  0, 0, -1, -1, 0, 0, 0, -1, 0, ],
    [  0, 0, -1, 0, -1, 0, -1, 0, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [  0, 0, -1, -1, 0, 0, 0, -1, 0, ],
    [  0, 0, 1, 0, 1, 0, 1, 0, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [  0, 0, -1, 0, -1, 0, -1, 0, 0, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
]

hex_VSpU = [
  [ #/* 1 */
    [ -1, 1, 0,  0,  0,  0,  0,  0,  0, ],
    [ -1, 0, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, 0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ 1, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ -1, 0, 0, -1, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1.0/3, -1.0/3, 0,  0,  0,  0,  0,  0,  0, ],
    [ 1.0/3, -2.0/3, 0,  0,  0,  0,  0,  0,  0, ],
    [ 0, 0, -1.0/2,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ -1.0/3, 0, 0, -1.0/3, 0, 0,  0,  0,  0, ],
    [ 1.0/3, 0, 0, -2.0/3, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ -1, 0, 0, 1, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 2, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ -1, 1, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 0, 0, 0, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 1, 0, 0, -1, 0, 0, 0, 0, 0, ],
    [ -1, 0, 0, 0, 0, 0, 0, 0, 0, ],
    [ 0, 0, 0, 0, 0, -1.0/2, 0, 0, 0, ],
  ],
]

hex_generators = [
  [ #/* 1 */
    [  1, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  1, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [  1, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [  -1, 1, 0, -1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [  -1, 1, 0, -1, 0, 0, 0, 0, -1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [  -1, 1, 0, -1, 0, 0, 0, 0, -1, ],
    [  0, 1, 0, 1, 0, 0, 0, 0, 1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [  1, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [  1, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  0, -1, 0, -1, 0, 0, 0, 0, -1, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
]

cub_VSpU = [
  [ #/* 1 */
    [ -1.0/2, 1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1.0/2, 1.0/2, 0, 1, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1.0/2, 1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 1.0/2, -1.0/2, 0, -1, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, -1.0/2, 0, -1, 0, -1,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, -1,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ 0, -1.0/2, 0, -1, 0, 1,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 0, 1.0/2, 0, 0, 0, -1,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ -1.0/2, -1.0/2, 0, 1, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ -1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 1.0/2, -1.0/2, 0, 0, 0, 0,  0,  0,  0, ],
    [ 1.0/2, 1.0/2, 0, -1, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, 0, -1.0/2, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 1,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 0, 0, 1.0/2, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 1.0/2, 0, 0, -1,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, -1, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, ],
  ],
  [ #/* 10 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, 0, 1, 0, 1, -1.0/2, 0, 0, ],
    [ 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, ],
  ],
]

cub_F_VSpU = [
  [ #/* 1 */
    [ 0, 0, -1.0/2, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1, 1.0/2, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, 1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ 0, 1.0/2, -1.0/2, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 1.0/2, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, -1.0/2, -1.0/2, 0, 1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 0, 1.0/4, -1.0/4, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -3.0/4, -1.0/4, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 1.0/4, -1.0/4, 1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ 0, 1.0/2, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 0, -1.0/2, 0,  0,  0,  0, ],
    [ 0, -1.0/2, 0, -1, 1.0/2, 0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ -1.0/4, 1.0/4, 0, -1.0/2, 0, 0,  0,  0,  0, ],
    [ -1.0/4, -3.0/4, 0, 1.0/2, 0, 0,  0,  0,  0, ],
    [ -1.0/4, 1.0/4, 0, 1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ 0, 0, 1.0/2, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, -1, -1.0/2, -1.0/2, 0, 0,  0,  0,  0, ],
    [ 0, 0, -1.0/2, -1.0/2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ 0, -1.0/2, 0, -1.0/2, 0, -1.0/2,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 1.0/2, 0, 1.0/2,  0,  0,  0, ],
    [ 0, -1.0/2, 0, 1.0/2, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 0, 0, 1.0/2, -1.0/2, 0, 1.0/2,  0,  0,  0, ],
    [ 0, 0, 1.0/2, 1.0/2, 0, -1.0/2,  0,  0,  0, ],
    [ 0, 0, -1.0/2, -1.0/2, 0, -1.0/2,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, -1, 0, -1, 0, 0, 1.0/2, 0, 0, ],
    [ 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, ],
  ],
  [ #/* 10 */
    [ 0, 0, 0, 0, 0, 0, -1.0/2, 0, 0, ],
    [ 0, 0, -1, -2, 0, 0, 3.0/2, 0, 0, ],
    [ 0, 0, 0, 1, 0, 0, -1.0/2, 0, 0, ],
  ],
]

cub_I_VSpU = [
  [ #/* 1 */
    [ 0, -1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 1, -1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 0, -1, 0, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [ -1, 0, 1, -1, 0, 0,  0,  0,  0, ],
    [ 0, 0, 1, -1, 0, 0,  0,  0,  0, ],
    [ 1, 0, -1, 0, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [ 1, 0, -1, -2, 0, -1,  0,  0,  0, ],
    [ 1, 0, -1, -1, 0, 0,  0,  0,  0, ],
    [ 1, 0, -1, -1, 0, -1,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [ -1, 0, 1, 0, 0, -1,  0,  0,  0, ],
    [ 3, 0, -1, -3, 0, 2,  0,  0,  0, ],
    [ -3, 0, 1, 3, 0, -3,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [ 1, 2, -5, -7, 0, 0,  0,  0,  0, ],
    [ 1, 1, -4, -5, 0, 0,  0,  0,  0, ],
    [ 0, 1, -2, -2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [ -2, 1, 0, 1, 0, 0,  0,  0,  0, ],
    [ 1, -1, 0, -1, 0, 0,  0,  0,  0, ],
    [ 2, -1, 0, -2, 0, 0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [ -1, 0, 0, 0, 0, -1,  0,  0,  0, ],
    [ -1, 0, 0, 1, 0, 0,  0,  0,  0, ],
    [ -1, 0, 0, 1, 0, -1,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [ 1, 0, 0, 0, -2, 1,  0,  0,  0, ],
    [ -1, 0, 0, 0, 1, -1,  0,  0,  0, ],
    [ 1, 0, 0, 0, -1, 0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [ -2, -3, 0, -1, 0, 0, 1, -1, 1, ],
    [ -1, -3, 0, -1, 0, 0, 1, -1, 1, ],
    [ 0, -1, 0, 0, 0, 0, 0, 0, 0, ],
  ],
  [ #/* 10 */
    [ -1, 0, 0, 0, 0, -1, 0, -1, 1, ],
    [ -1, 0, 0, 1, 0, 0, 0, -1, 1, ],
    [ -1, 0, 0, 1, 0, -1, 0, -1, 1, ],
  ],
]

cub_generators = [
  [ #/* 1 */
    [  0, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 2 */
    [  0, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  0, 0, -1, -1, 0, 0, 0, -1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 3 */
    [  -1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 4 */
    [  -1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [  0, 0, -1, -1, 0, 0, 0, -1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 5 */
    [  0, 1, 0, -1, 0, 0, 0, 0, -1, ],
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 6 */
    [  0, 1, 0, -1, 0, 0, 0, 0, -1, ],
    [  0, 0, -1, -1, 0, 0, 0, -1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 7 */
    [  1, 0, 0, 0, 1, 0, 0, 0, -1, ],
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 8 */
    [  1, 0, 0, 0, 1, 0, 0, 0, -1, ],
    [  0, 0, -1, -1, 0, 0, 0, -1, 0, ],
    [   0,  0,  0,  0,  0,  0,  0,  0,  0, ],
  ],
  [ #/* 9 */
    [  0, -1, 0, 1, 0, 0, 0, 0, 1, ],
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
  [ #/* 10 */
    [  -1, 0, 0, 0, -1, 0, 0, 0, 1, ],
    [  0, 0, 1, 1, 0, 0, 0, 1, 0, ],
    [  -1, 0, 0, 0, -1, 0, 0, 0, -1, ],
  ],
]


def ChangeOrigin(origin, center):   # // p(prim) --> p(conv)
    tp_ori = np.zeros(3)
    if center == 'PRIMITIVE':
        tp_ori = origin.copy()
    elif center == 'BODY':
        tp_ori = np.dot(origin, np.transpose(I_mat))
    elif center == 'FACE':
        tp_ori = np.dot(origin, np.transpose(F_mat))
    elif center == 'A_FACE':
        tp_ori = np.dot(origin, np.transpose(A_mat))
    elif center == 'B_FACE':
        tp_ori = np.dot(origin, np.transpose(B_mat))
    elif center == 'C_FACE':
        tp_ori = np.dot(origin, np.transpose(C_mat))
    elif center == 'R_CENTER':
        tp_ori = np.dot(origin, np.transpose(R_mat))

    return tp_ori


def TransformTrans(trans, center):
    tp_trans = np.zeros(3)
    if center == 'PRIMITIVE':
        tp_trans = trans.copy()
    elif center == 'BODY':
        tp_trans = np.dot(np.linalg.inv(I_mat), trans)
    elif center == 'FACE':
        tp_trans = np.dot(np.linalg.inv(F_mat), trans)
    elif center == 'A_FACE':
        tp_trans = np.dot(np.linalg.inv(A_mat), trans)
    elif center == 'B_FACE':
        tp_trans = np.dot(np.linalg.inv(B_mat), trans)
    elif center == 'C_FACE':
        tp_trans = np.dot(np.linalg.inv(C_mat), trans)
    elif center == 'R_CENTER':
        tp_trans = np.dot(np.linalg.inv(R_mat), trans)

    tp2 = tp_trans.copy()
    for k in range(3):
        if tp2[k] < 0.0:
            tp2[k] = int(tp2[k] - 0.5)
        else:
            tp2[k] = int(tp2[k] + 0.5)
    tp_trans = tp_trans - tp2
    for k in range(3):
        if tp_trans[k] < 0.0:
            tp_trans[k] += 1.0

    return tp_trans


def TransformRot(rot, center):
    P = np.zeros((3, 3))
    if center == 'PRIMITIVE':
        P = np.identity(3)
    elif center == 'BODY':
        P = I_mat.copy()
    elif center == 'FACE':
        P = F_mat.copy()
    elif center == 'A_FACE':
        P = A_mat.copy()
    elif center == 'B_FACE':
        P = B_mat.copy()
    elif center == 'C_FACE':
        P = C_mat.copy()
    elif center == 'R_CENTER':
        P = R_mat.copy()

    tp_rot1 = np.dot(np.linalg.inv(P), rot)     # // new_rot W'=QWP
    tp_rot = np.dot(tp_rot1, P)  # // new_rot W'=QWP
    '''
        tp_rot2 = tp_rot.copy()
        # // find matrix whose elements are all integer
        # print('tp det:', np.linalg.det(tp_rot))

        for j in range(3):
            for k in range(3):
                if tp_rot2[j, k] < 0.0:
                    tp_rot2[j, k] = int(tp_rot2[j, k] - 0.5)
                else:
                    tp_rot2[j, k] = int(tp_rot2[j, k] + 0.5)
        # print('1:', tp_rot1)
        # print('2:', tp_rot2)
        tp_flag = True
        for j in range(3):
            for k in range(3):
                if abs(tp_rot2[j, k] - tp_rot[j, k]) > 0.00001:
                    tp_flag = False
                    break
                else:
                    tp_flag = True
        if tp_flag:
            if abs(np.linalg.det(tp_rot2)) == 1:  # //tp_rot1 or tp_rot2
                return tp_rot2
        else:
            return None
    '''
    return tp_rot


def FinalMatch(prim_latt, shift, new_symm, center, ref_rot, ref_tr):
    #print('how many:', new_symm[1][0])
    for i in range(len(new_symm)):
        is_found = 0
        for j in range(len(ref_rot)):
            if (np.array(new_symm[i][0]) == ref_rot[j]).all():
                w_pri = TransformTrans(ref_tr[j], center)
                w_pri_rot = TransformTrans(new_symm[i][1], center)
                W_pri = TransformRot(ref_rot[j], center)
                tolerance = 0.00001
                vec1 = w_pri_rot - w_pri + shift
                vec2 = np.dot(W_pri, shift)
                vec_diff = vec1 - vec2
                #print('diff: ', vec_diff)
                tp_diff = vec_diff.copy()
                for k in range(3):
                    if tp_diff[k] < 0.0:
                        tp_diff[k] = int(tp_diff[k] - 0.5)
                    else:
                        tp_diff[k] = int(tp_diff[k] + 0.5)

                nvec_diff = vec_diff - tp_diff
                if np.linalg.norm(np.dot(np.transpose(prim_latt), np.transpose(nvec_diff))) < tolerance:  # // np.dot(latt, nvec_diff) is better?
                    is_found = 1  # overlap
                    break
        if not is_found:
            return 0

    return 1


def HallSym(prim_latt, hall_num, new_symm, center, generator, VSpU):
    # // first, the number of symmetry should be the same as that of reference
    ref_rot, ref_tr = halldata.GetReferOper(hall_num)
    if len(ref_rot) != len(new_symm):
        return 0, None

    rot = []
    trans = []
    for i in range(3):
        tp_rot = (np.array(generator[i])).reshape(3, 3)
        rot.append(tp_rot)
        trans.append(np.zeros(3))
    #print('c1', rot)

    #is_found_tot = 0
    for i in range(3):
        if (rot[i] == np.zeros(3)).all():
            #print('checkidentity')
            continue
        is_found = 0
        for j in range(len(new_symm)):
            tp1 = np.array(new_symm[j][0])
            tp2 = np.array(rot[i])
            if (tp1 == tp2).all():
                is_found = 1
                trans[i] = new_symm[j][1]
                #print('found', rot[i], trans[i], i)
                break
        if not is_found:
            #print('no??')
            return 0, None

    # // get origin shift
    tp_trans = []
    delta_w = []
    for i in range(3):
        tp_trans.append(np.zeros(3))
        delta_w.append(np.zeros(3))

    for k in range(3):
        if np.linalg.det(rot[k]) == 0:
            continue
        is_found1 = 0
        tp_trans[k] = TransformTrans(trans[k], center)
        #tp_ref_tr = np.zeros(3)
        for j in range(len(ref_rot)):
            tp_ref_tr = TransformTrans(ref_tr[j], center)
            if (np.array(ref_rot[j]) == np.array(rot[k])).all():
                is_found1 = 1
                #tp_ref_tr = tp_trans[k] - tp_ref_tr
                #delta_w[k] = tp_ref_tr.copy()
                delta_w[k] = tp_trans[k] - tp_ref_tr
                break
        if not is_found1:
            #print('no2???')
            return 0, None

    tp_w = []
    for i in delta_w:
        for j in i:
            tp_w.append(j)
    #print('check tp_w: ', tp_w)

    tp2 = tp_w.copy()
    for i in range(len(tp2)):
        if tp2[i] < 0.0:
            tp2[i] = int(tp2[i] - 0.5)
        else:
            tp2[i] = int(tp2[i] + 0.5)
    for i in range(len(tp2)):
        tp_w[i] = tp_w[i] - tp2[i]
        if tp_w[i] < 0.0:
            tp_w[i] += 1.0
    #print('check new tp_w: ', tp_w)

    shift = np.zeros(3)
    for i in range(3):
        for j in range(9):
            shift[i] += VSpU[i][j] * tp_w[j]
        tp2 = shift.copy()
        for k in range(3):
            if tp2[k] < 0.0:
                tp2[k] = int(tp2[k] - 0.5)
            else:
                tp2[k] = int(tp2[k] + 0.5)
        shift = shift - tp2
        for k in range(3):
            if shift[k] < 0.0:
                shift[k] += 1.0
    #print('shift is', shift)

    if FinalMatch(prim_latt, shift, new_symm, center, ref_rot, ref_tr):
        print('match', center)
        return 1, shift
    else:
        #print('not found', hall_num)
        return 0, None


def MatchHall(conv_latt, hall_num, new_symm, new_cen):
    #print('center1:\n', new_cen)
    prim_latt = np.zeros((3, 3))
    if new_cen == 'PRIMITIVE':
        prim_latt = conv_latt.copy()

    elif new_cen == 'BODY':
        prim_latt = np.dot(np.transpose(I_mat), conv_latt)

    elif new_cen == 'FACE':
        prim_latt = np.dot(np.transpose(F_mat), conv_latt)

    elif new_cen == 'A_FACE':
        prim_latt = np.dot(np.transpose(A_mat), conv_latt)

    elif new_cen == 'B_FACE':
        prim_latt = np.dot(np.transpose(B_mat), conv_latt)

    elif new_cen == 'C_FACE':
        prim_latt = np.dot(np.transpose(C_mat), conv_latt)

    elif new_cen == 'R_CENTER':
        prim_latt = np.dot(np.transpose(R_mat), conv_latt)

    # // TRICLINIC
    if hall_num in range(1, 3):
        for i in range(2):
            flag, shift = HallSym(prim_latt, hall_num, new_symm, 'PRIMITIVE', tricli_generators[i], tricli_VSpU[i])
            if shift is not None:
                origin = ChangeOrigin(shift, 'PRIMITIVE')
                return 1, origin
        return 0, None

    # // MONOCLINIC
    if hall_num in range(3, 108):
        for i in range(9):
            if new_cen == 'PRIMITIVE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, mono_generators[i], mono_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'A_FACE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, mono_generators[i], mono_A_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'B_FACE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, mono_generators[i], mono_B_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'C_FACE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, mono_generators[i], mono_C_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'BODY':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, mono_generators[i], mono_I_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
        return 0, None

    # // ORTHOGONAL
    if hall_num in range(108, 349):
        for i in range(5):
            if new_cen == 'PRIMITIVE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, ortho_generators[i], ortho_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'A_FACE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, ortho_generators[i], ortho_A_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'B_FACE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, ortho_generators[i], ortho_B_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'C_FACE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, ortho_generators[i], ortho_C_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'BODY':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, ortho_generators[i], ortho_I_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'FACE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, ortho_generators[i], ortho_F_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
        return 0, None

    # // TETRAGONAL
    if hall_num in range(349, 430):
        for i in range(8):
            if new_cen == 'PRIMITIVE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, tetra_generators[i], tetra_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'BODY':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, tetra_generators[i], tetra_I_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin

        return 0, None

    # // TRIGONAL
    if hall_num in range(430, 462):
        # // RHOMBO
        if hall_num in [433, 434, 436, 437, 444, 445, 450, 451, 452, 453, 458, 459, 460, 461]:
            if hall_num in [433, 436, 444, 450, 452, 458, 460]:
                for i in range(8):
                    flag, shift = HallSym(prim_latt, hall_num, new_symm, 'R_CENTER', rhombo_h_generators[i], rhombo_h_VSpU[i])
                    if shift is not None:
                        origin = ChangeOrigin(shift, 'R_CENTER')
                        return 1, origin
                return 0, None
            else:
                for i in range(8):
                    flag, shift = HallSym(prim_latt, hall_num, new_symm, 'PRIMITIVE', rhombo_p_generators[i], rhombo_p_VSpU[i])
                    if shift is not None:
                        origin = ChangeOrigin(shift, 'PRIMITIVE')
                        return 1, origin
                return 0, None
        else:
            # // TRIGONAL
            for i in range(13):
                flag, shift = HallSym(prim_latt, hall_num, new_symm, 'PRIMITIVE', trigo_generators[i], trigo_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, 'PRIMITIVE')
                    return 1, origin
        return 0, None

    # // HEXAGONAL
    if hall_num in range(462, 489):
        for i in range(8):
            flag, shift = HallSym(prim_latt, hall_num, new_symm, 'PRIMITIVE', hex_generators[i], hex_VSpU[i])
            if shift is not None:
                origin = ChangeOrigin(shift, 'PRIMITIVE')
                return 1, origin
        return 0, None

    # // CUBIC
    if hall_num in range(489, 531):
        for i in range(10):
            if new_cen == 'PRIMITIVE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, cub_generators[i], cub_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'BODY':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, cub_generators[i], cub_I_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin
            elif new_cen == 'FACE':
                flag, shift = HallSym(prim_latt, hall_num, new_symm, new_cen, cub_generators[i], cub_F_VSpU[i])
                if shift is not None:
                    origin = ChangeOrigin(shift, new_cen)
                    return 1, origin

        return 0, None


def MatchHallMono(conv_latt, hall_num, num_hall_type, conv_symm, center):

    from spgroup import GetConvSymm

    new_latt = np.zeros((3, 3))
    new_cen = None
    for i in range(36):
        if center == 'C_FACE':
            new_cen = change_of_cen_mono[i]
        else:
            new_cen = center

        new_latt = np.dot(np.transpose(change_of_b_mono[i]), conv_latt)

        k = 0
        tp_vec = np.zeros((2, 3))
        for j in range(3):
            if j != change_of_uni_ax_mono[i]:
                tp_vec[k] = new_latt[j]
                k += 1

        if np.dot(tp_vec[0], tp_vec[1]) > 0.000000001:
            continue

        if num_hall_type == 3:
            if np.linalg.norm(tp_vec[0]) > np.linalg.norm(tp_vec[1]) + 0.0000000001:
                continue

        new_symm = GetConvSymm('PRIMITIVE', change_of_b_mono[i], conv_symm)
        if new_symm:
            flag, origin = MatchHall(new_latt, hall_num, new_symm, new_cen)
            if flag:
                return 1, new_latt, origin

    return 0, None, None


def MatchHallOrtho(conv_latt, hall_num, conv_symm, center, num_free_ax):
    from spgroup import GetConvSymm
    tolerance = 0.0000000001
    new_latt = np.zeros((3, 3))
    new_cen = None
    #print(center)
    for i in range(6):
        if center == 'C_FACE':
            new_cen = change_of_cen_ortho[i]
        else:
            new_cen = center

        new_latt = np.dot(np.transpose(change_of_b_ortho[i]), conv_latt)

        if num_free_ax == 2:
            k = 0
            tp_vec = np.zeros((2, 3))
            for j in range(3):
                if j != change_of_uni_ax_ortho[i]:
                    tp_vec[k] = new_latt[j]
                    k += 1
            if np.linalg.norm(tp_vec[0]) > np.linalg.norm(tp_vec[1]) + tolerance:
                continue

        if num_free_ax == 3:
            tp_vec = new_latt.copy()
            if (np.linalg.norm(tp_vec[0]) > np.linalg.norm(tp_vec[1]) + tolerance) or (np.linalg.norm(tp_vec[0]) > np.linalg.norm(tp_vec[2]) + tolerance):
                continue

        if num_free_ax == 6:
            tp_vec = new_latt.copy()
            if (np.linalg.norm(tp_vec[0]) > np.linalg.norm(tp_vec[1]) + tolerance) or (np.linalg.norm(tp_vec[1]) > np.linalg.norm(tp_vec[2]) + tolerance):
                continue

        new_symm = GetConvSymm('PRIMITIVE', change_of_b_ortho[i], conv_symm)
        if new_symm != []:
            flag, origin = MatchHall(new_latt, hall_num, new_symm, new_cen)
            if flag:
                return 1, new_latt, origin

    return 0, None, None